import { IPSModelObject } from './ipsmodel-object';
import { IPSModelService } from './ipsmodel-service';
import { IPSApplication } from './app/ipsapplication';
import { PSApplicationImpl } from './app/psapplication-impl';
import { isNilOrEmpty, isObject, notNilEmpty } from 'qx-util';
import { IPSModelServiceProxy } from './ipsmodel-service-proxy';
import {
  formatPath,
  getByFunc,
  findRelatedPSAppDataEntity,
  ModelServiceStore,
  getControl,
  ModelQueue,
  LogUtil,
  findPSAppCounterRefByParent,
} from './core';
import { IPSAppView } from './app/view/ipsapp-view';
import { IPSAppDataEntity } from './app/dataentity/ipsapp-data-entity';
import { IPSControlHandler } from './control/ipscontrol-handler';
import { IPSControl } from './control/ipscontrol';
import { IPSAppViewUIAction } from './app/view/ipsapp-view-uiaction';
import { IPSControlContainer, IPSDBPortletPart, IPSDEForm } from './exports';
import { ApiConfig } from './global/app-config';

/**
 * 模型服务
 *
 * @export
 * @abstract
 * @class PSModelServiceImplBaseBase
 * @implements {IPSModelService}
 */
export abstract class PSModelServiceImplBaseBase implements IPSModelService {
  /**
   * 数据缓存对象
   *
   * @type {ModelServiceStore}
   */
  readonly store: ModelServiceStore = new ModelServiceStore();

  /**
   * 用于请求JSON文件
   *
   * @author chitanda
   * @date 2021-05-12 16:05:02
   */
  getModelJson: (modelPath: string) => Promise<IModel>;

  /**
   * 应用对象
   *
   * @private
   * @type {IPSApplication}
   */
  private iPSApplication: IPSApplication = null;

  /**
   * 获取应用对象
   *
   * @return {*}  {IPSApplication}
   */
  get app(): IPSApplication {
    return this.getPSApplication();
  }
  getPSApplication(): IPSApplication {
    if (this.iPSApplication == null) {
      const strPath = '/' + 'PSSYSAPP.json';
      const iPSModelObject = this.store.modelObject.get(strPath);
      if (iPSModelObject == null) {
        const app = this.createPSApplication();
        this.store.modelObject.set(strPath, app);
        app.init(this.getPSModelService('PSApplication', null), null, strPath);
        this.iPSApplication = app;
        return this.iPSApplication;
      }
    }
    return this.iPSApplication;
  }

  /**
   * 创建应用对象
   *
   * @protected
   * @return {*}  {IPSApplication}
   */
  protected createPSApplication(): IPSApplication {
    return new PSApplicationImpl();
  }

  /**
   * 异步加载模型
   *
   * @protected
   * @param {string} strPath
   * @return {*}  {Promise<IModel>}
   */
  protected loadModel(strPath: string): Promise<IModel> {
    return new Promise(async resolve => {
      try {
        if (this.getModelJson) {
          const queueTag = `${strPath}_http`;
          if (ModelQueue.isQueue(queueTag)) {
            return ModelQueue.add(queueTag, resolve);
          }
          ModelQueue.add(queueTag, resolve);
          const model = await this.getModelJson(formatPath(strPath));
          ModelQueue.done(queueTag, model);
          return;
        }
        throw new Error(`未设置「getModelJson」获取模型方法，模型包无法运行!`);
      } catch (err) {
        LogUtil.error(err);
      }
      return null;
    });
  }

  /**
   * 加载多语言模型
   *
   * @author chitanda
   * @date 2021-05-27 16:05:50
   * @return {*}  {Promise<void>}
   */
  async loadLanguage(): Promise<void> {
    if (notNilEmpty(ApiConfig.lang)) {
      const data: any = await this.loadModel(
        `/PSAPPLANS/${ApiConfig.lang}.json`,
      );
      if (notNilEmpty(data)) {
        const items: any[] = data.getAllPSLanguageItems;
        if (notNilEmpty(items)) {
          items.forEach(item => {
            this.store.languageCache.set(item.lanResTag, item.content);
          });
        }
      }
    }
  }

  /**
   * 获取模型对象
   *
   * @param {string} cls
   * @param {string} strPath
   * @return {*}  {Promise<IPSModelObject>}
   */
  getPSModel(cls: string, strPath: string): Promise<IPSModelObject> {
    return new Promise<IPSModelObject>(async resolve => {
      //从缓存获取
      const iPSModelObject = this.store.modelObject.get(strPath);
      if (iPSModelObject != null) {
        resolve(iPSModelObject);
        return;
      }
      const queueTag = strPath;
      if (ModelQueue.isQueue(queueTag)) {
        return ModelQueue.add(queueTag, resolve);
      }
      ModelQueue.add(queueTag, resolve);
      const model = await this.loadModel(strPath);
      if (model) {
        // 创建模型对象
        const psModelObj = this.createPSModelObject(null, cls, model);
        if (psModelObj != null) {
          const iPSModelService = this.getPSModelService(cls, psModelObj);
          psModelObj.init(iPSModelService, null, strPath, model);
          this.store.setModelCache(cls, strPath, psModelObj);
        } else {
          LogUtil.warn(`模型对象[${cls}]创建失败!`);
        }
        return ModelQueue.done(queueTag, psModelObj);
      }
      return ModelQueue.done(queueTag, null);
    });
  }

  /**
   * 根据类型建立模型对象
   *
   * @protected
   * @param {IPSModelObject} parentPSModelObject
   * @param {string} cls
   * @param {IModel} [objNode]
   * @return {*}  {(IPSModelObject | null)}
   */
  protected createPSModelObject(
    parentPSModelObject: IPSModelObject,
    cls: string,
    objNode?: IModel,
  ): IPSModelObject | null {
    return this.onCreatePSModelObject(parentPSModelObject, cls, objNode);
  }

  /**
   * 创建指定对象
   *
   * @protected
   * @param {IPSModelObject} _parentPSModelObject
   * @param {string} _cls
   * @param {IModel} [_objNode]
   * @return {*}  {(IPSModelObject | null)}
   */
  protected onCreatePSModelObject(
    _parentPSModelObject: IPSModelObject,
    _cls: string,
    _objNode?: IModel,
  ): IPSModelObject | null {
    return null;
  }

  /**
   * 根据类型，获取模型服务
   *
   * @protected
   * @param {string} cls
   * @return {*}  {IPSModelService}
   */
  protected getPSModelService(
    cls: string,
    modelObject: IPSModelObject,
  ): IPSModelService {
    if (modelObject) {
      const iPSModelService = this.store.modelService.get(modelObject.cls);
      if (iPSModelService == null) {
        const iPSModelServiceProxy = this.createPSModelServiceProxy(
          cls,
          modelObject,
        );
        if (iPSModelServiceProxy != null) {
          iPSModelServiceProxy.init(this, modelObject.cls);
          this.store.modelService.set(modelObject.cls, iPSModelServiceProxy);
          return iPSModelServiceProxy;
        }
        this.store.modelService.set(modelObject.cls, this);
        return this;
      }
      return iPSModelService;
    }
    return this;
  }

  /**
   * 根据类型创建模型代理类
   *
   * @protected
   * @param {string} _cls
   * @param {IPSModelObject} _modelObject
   * @return {*}  {IPSModelServiceProxy}
   */
  protected createPSModelServiceProxy(
    _cls: string,
    _modelObject: IPSModelObject,
  ): IPSModelServiceProxy {
    return null;
  }

  // /**
  //  * 获取真实模型
  //  *
  //  * @param {IPSModelObject} _relatedPSModelObject
  //  * @param {*} objectNode
  //  * @return {*}
  //  */
  // getRealModel(_relatedPSModelObject: IPSModelObject, objectNode: any) {
  //   return objectNode;
  // }

  /**
   * 根据路径获取模型
   *
   * @param {IPSModelObject} _relatedPSModelObject
   * @param {string} filePath
   */
  async getModel(
    _relatedPSModelObject: IPSModelObject,
    filePath: string,
  ): Promise<IModel> {
    return this.loadModel(filePath);
  }

  /**
   * 查找指定模型，在应用级特殊处理。根据codeName查询
   *
   * @author chitanda
   * @date 2021-07-02 15:07:45
   * @protected
   * @param {IPSModelObject} _relatedPSModelObject
   * @param {string} cls
   * @param {string} tag
   * @param {string} [strTag]
   * @return {*}  {(IPSModelObject | null)}
   */
  protected getPSModel4ForAppByCodeName(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    tag: string,
    strTag?: string,
  ): IPSModelObject | null {
    // 应用功能特殊处理
    if (cls === 'app.func.IPSAppFunc') {
      return this.getPSAppFunc(tag);
    } else if (strTag === 'getPSAppViewMsg') {
      return this.app.findPSAppViewMsg(tag);
    } else if (cls === 'app.view.IPSAppViewEngine') {
      const view = relatedPSModelObject.getParentPSModelObject(
        'app.view.IPSAppView',
      ) as IPSAppView;
      if (view) {
        return view.findPSAppViewEngine(tag);
      }
    } else if (cls === 'app.view.IPSAppViewLogic') {
      const container = relatedPSModelObject.getParentPSModelObject(
        'control.IPSControlContainer',
      ) as IPSControlContainer;
      if (container) {
        return container.findPSAppViewLogic(tag);
      }
    }
  }

  /**
   * 查找指定模型，在应用级特殊处理。根据path查询
   *
   * @author chitanda
   * @date 2021-07-02 15:07:00
   * @protected
   * @param {IPSModelObject} _relatedPSModelObject
   * @param {string} cls
   * @param {string} strPath
   * @param {string} [strTag]
   * @return {*}  {(IPSModelObject | null)}
   */
  protected getPSModel4ForAppByPath(
    _relatedPSModelObject: IPSModelObject,
    cls: string,
    strPath: string,
    _strTag?: string,
  ): IPSModelObject | null {
    if (
      cls === 'app.codelist.IPSAppCodeList' ||
      cls === 'codelist.IPSCodeList'
    ) {
      return this.getPSAppCodeList(strPath);
    }
  }

  /**
   * 查找指定模型之前
   *
   * @author chitanda
   * @date 2021-07-02 15:07:29
   * @protected
   * @param {IPSModelObject} relatedPSModelObject
   * @param {string} cls
   * @param {IModel} obj
   * @param {string} [_strTag]
   * @return {*}  {(IPSModelObject | null)}
   */
  protected getPSModel4Before(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    obj: IModel,
    strTag?: string,
  ): IPSModelObject | null {
    if (
      cls === 'app.dataentity.IPSAppDEField' &&
      relatedPSModelObject &&
      !relatedPSModelObject.instanceof('app.dataentity.IPSAppDataEntity')
    ) {
      return relatedPSModelObject.getChildPSModelObject(cls, obj);
    }
    if (
      strTag === 'getContentPSControl' &&
      relatedPSModelObject &&
      relatedPSModelObject.instanceof('control.dashboard.IPSDBPortletPart')
    ) {
      return getControl(relatedPSModelObject as IPSDBPortletPart, obj.name);
    }
    if (
      cls === 'res.IPSSysPFPlugin' &&
      strTag === 'getPSSysPFPlugin' &&
      obj.runtimeObject === true
    ) {
      const pluginRefs = this.app.getAllPSAppPFPluginRefs();
      const pluginRef = pluginRefs.find(item => {
        return item.pluginCode === obj.pluginCode;
      });
      if (pluginRef) {
        return pluginRef;
      }
    }
    return null;
  }

  /**
   * 查找指定模型
   *
   * @author chitanda
   * @date 2021-06-08 20:06:44
   * @param {IPSModelObject} relatedPSModelObject 相关模型
   * @param {string} cls 类型标识
   * @param {IModel} obj 模型
   * @param {string} [strTag] 方法标识
   * @return {*}  {IPSModelObject}
   */
  getPSModel4(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    obj: IModel,
    strTag?: string,
  ): IPSModelObject {
    try {
      const data = this.getPSModel4Before(
        relatedPSModelObject,
        cls,
        obj,
        strTag,
      );
      if (data) {
        return data;
      }
      const bModelRef = obj.modelref || false;
      if (bModelRef) {
        const data = this.getPSModel4ForAppByCodeName(
          relatedPSModelObject,
          cls,
          obj.id,
          strTag,
        );
        if (data) {
          return data;
        }
        if (notNilEmpty(obj.path)) {
          const data = this.getPSModel4ForAppByPath(
            relatedPSModelObject,
            cls,
            obj.path,
            strTag,
          );
          if (data) {
            return data;
          }
          const strPath = obj.path;
          // 加载模型
          const iPSModelObject = this.store.modelObject.get(strPath);
          if (iPSModelObject == null) {
            const t = this.createPSModelObject(relatedPSModelObject, cls, obj);
            this.store.setModelCache(cls, strPath, t);
            // 初始化
            t.init(
              this.getPSModelService(cls, t),
              relatedPSModelObject,
              strPath,
              null,
              obj,
            );
            return t;
          }
          return iPSModelObject;
        } else {
          // 相对父模型
          if (relatedPSModelObject == null) {
            LogUtil.error('父对象无效');
            return;
          }
          return relatedPSModelObject.getChildPSModelObject(cls, obj);
        }
      } else {
        const path = obj.path || obj.dynaModelFilePath;
        if (notNilEmpty(path)) {
          const strPath = path;
          const iPSModelObject = this.store.modelObject.get(strPath);
          if (iPSModelObject == null) {
            const t = this.createPSModelObject(relatedPSModelObject, cls, obj);
            this.store.setModelCache(cls, strPath, t);
            t.init(
              this.getPSModelService(cls, t),
              relatedPSModelObject,
              null,
              obj,
            );
            return t;
          }
          return iPSModelObject;
        } else {
          const t = this.createPSModelObject(relatedPSModelObject, cls, obj);
          t.init(
            this.getPSModelService(cls, t),
            relatedPSModelObject,
            null,
            obj,
          );
          return t;
        }
      }
    } catch (err) {
      LogUtil.warn(`异常：${err.message}，类型「${cls}」。`);
    }
  }

  /**
   * 从集合里边提取，符合目标key的对象
   *
   * @param {IPSModelObject} _relatedPSModelObject 相关模型
   * @param {string} cls 目标对象
   * @param {IPSModelObject[]} list 目标集合
   * @param {*} data 需要查找的key
   * @return {*}
   */
  getPSModel5(
    _relatedPSModelObject: IPSModelObject,
    cls: string,
    list: IPSModelObject[],
    data: string | IModel,
  ) {
    if (list == null || data == null) {
      if (data != null) {
        const strTag = this.getPSModelTag(cls, data);
        LogUtil.warn(`无法获取指定模型[${cls}]，标识为[${strTag}]`);
      } else {
        LogUtil.warn(`无法获取指定模型[${cls}]，没有指定标识`);
      }
      return null;
    }
    const strTag: string = this.getPSModelTag(cls, data);
    for (const item of list) {
      if (this.testPSModel(cls, item, strTag)) {
        return item;
      }
    }
    LogUtil.warn(`无法获取指定模型[${cls}]，标识为[${strTag}]`);
    return null;
  }

  /**
   * 测试复合目标对象
   *
   * @protected
   * @param {string} _cls
   * @param {IPSModelObject} obj
   * @param {string} strTag
   * @return {*}  {boolean}
   */
  protected testPSModel(
    _cls: string,
    obj: IPSModelObject,
    strTag: string,
  ): boolean {
    if (notNilEmpty(strTag) && notNilEmpty(obj)) {
      return obj.id === strTag;
    }
    return false;
  }

  /**
   * 获取模型标识
   *
   * @protected
   * @param {string} cls
   * @param {(string | IModel)} objKey
   * @return {*}  {string}
   */
  protected getPSModelTag(cls: string, objKey: string | IModel): string {
    if (typeof objKey === 'string') {
      return objKey as string;
    }
    if (isObject(objKey)) {
      const obj = objKey as IModel;
      if (obj.modelref === true) {
        let strTag = obj.path;
        if (isNilOrEmpty(strTag)) {
          strTag = obj.id;
          if (isNilOrEmpty(strTag)) {
            LogUtil.warn(`无法计算模型[${cls}]标识`);
          }
        }
        return strTag;
      } else {
        let strTag = obj.dynaModelFilePath;
        if (notNilEmpty(strTag)) {
          return strTag;
        }
        strTag = obj.codeName;
        if (notNilEmpty(strTag)) {
          return strTag;
        }
        strTag = obj.name;
        if (notNilEmpty(strTag)) {
          return strTag;
        }
        LogUtil.warn(`无法计算模型[${cls}]标识`);
      }
    }
    LogUtil.warn(`无法计算模型[${cls}]标识`);
  }

  /**
   *
   *
   * @param {IModel} obj
   * @return {*}  {IModel}
   */
  getRealObjectNode(obj: IModel): IModel {
    return obj;
  }

  /**
   * 查找子模型
   *
   * @param {IPSModelObject} relatedPSModelObject
   * @param {string} cls
   * @param {IModel} obj
   * @return {*}  {IPSModelObject}
   */
  getChildPSModelObject(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    obj: IModel,
  ): IPSModelObject {
    if (cls === 'app.dataentity.IPSAppDEField') {
      const entity = findRelatedPSAppDataEntity(relatedPSModelObject);
      if (entity) {
        return entity.findPSAppDEField(obj.codeName);
      }
    } else if (cls === 'app.view.IPSAppViewUIAction') {
      const uiActions = getByFunc(
        relatedPSModelObject,
        'getPSAppViewUIActions',
      ) as IPSAppViewUIAction[];
      if (uiActions && uiActions.length > 0) {
        return uiActions.find(item => this.testPSModel(cls, item, obj.id));
      }
    } else if (cls === 'control.IPSControlAction') {
      const control = this.getParentPSModelObject(
        relatedPSModelObject,
        'control.IPSControl',
      ) as IPSControl;
      if (control) {
        const controlHandler =
          control.getPSControlHandler() as IPSControlHandler;
        if (controlHandler) {
          return controlHandler.findPSControlHandlerAction(obj.id);
        }
      }
    } else if (cls === 'app.dataentity.IPSAppDEMethod') {
      const entity = findRelatedPSAppDataEntity(relatedPSModelObject);
      if (entity) {
        return entity.findPSAppDEMethod(obj.id);
      }
    } else if (cls === 'control.form.IPSDEFormItemUpdate') {
      const modelObject = relatedPSModelObject.getParentPSModelObject(
        'control.form.IPSDEForm',
      ) as IPSDEForm;
      if (modelObject) {
        return modelObject.findPSDEFormItemUpdate(obj.id);
      }
    } else if (
      cls === 'app.dataentity.IPSAppDEDataExport' ||
      cls === 'dataentity.dataexport.IPSDEDataExport'
    ) {
      const entity = findRelatedPSAppDataEntity(relatedPSModelObject);
      if (entity) {
        return entity.findPSAppDEDataExport(obj.id);
      }
    } else if (
      cls === 'app.dataentity.IPSAppDEDataImport' ||
      cls === 'dataentity.dataimport.IPSDEDataImport'
    ) {
      const entity = findRelatedPSAppDataEntity(relatedPSModelObject);
      if (entity) {
        return entity.findPSAppDEDataImport(obj.id);
      }
    } else if (cls === 'app.control.IPSAppCounterRef') {
      return findPSAppCounterRefByParent(relatedPSModelObject, obj);
    }
    LogUtil.warn(
      `无法从模型`,
      relatedPSModelObject,
      `获取指定类型[${cls}]子模型，标识为`,
    );
    return null;
  }

  /**
   * 获取父模型，如果本身模型符合接口返回自身
   *
   * @param {IPSModelObject} relatedPSModelObject
   * @param {string} cls
   * @return {*}  {IPSModelObject}
   */
  getParentPSModelObject(
    relatedPSModelObject: IPSModelObject,
    cls: string,
  ): IPSModelObject;
  getParentPSModelObject(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    tryMode?: boolean,
  ): IPSModelObject;
  getParentPSModelObject(
    relatedPSModelObject: IPSModelObject,
    cls: string,
    tryMode = true,
  ): IPSModelObject {
    if (cls === 'app.IPSApplication') {
      return this.getPSApplication();
    }
    const t = this.getParentPSModelObject2(relatedPSModelObject, cls);
    if (t == null) {
      if (cls === 'app.dataentity.IPSAppDataEntity') {
        if (relatedPSModelObject.instanceof('control.IPSControl')) {
          return (relatedPSModelObject as IPSControl).getPSAppDataEntity();
        }
        if (relatedPSModelObject.instanceof('app.view.IPSAppView')) {
          return (relatedPSModelObject as IPSAppView).getPSAppDataEntity();
        }
        const ctrl = this.getParentPSModelObject(
          relatedPSModelObject,
          'control.IPSControl',
          false,
        ) as IPSControl;
        if (ctrl) {
          return ctrl.getPSAppDataEntity();
        }
        const view = this.getParentPSModelObject(
          relatedPSModelObject,
          'app.view.IPSAppView',
          false,
        ) as IPSAppView;
        if (view) {
          return view.getPSAppDataEntity();
        }
      }
      if (tryMode) {
        LogUtil.warn(
          `无法从模型`,
          relatedPSModelObject,
          `获取指定类型[${cls}]父模型`,
        );
      }
    }
    return t;
  }

  protected getParentPSModelObject2(
    relatedPSModelObject: IPSModelObject,
    cls: string,
  ): IPSModelObject | null {
    if (relatedPSModelObject) {
      if (relatedPSModelObject.instanceof(cls)) {
        return relatedPSModelObject;
      }
      const p = relatedPSModelObject.getParentPSModelObject();
      if (p) {
        return this.getParentPSModelObject2(p, cls);
      }
    }
    return null;
  }

  /**
   * 获取应用视图
   *
   * @param {string} strPath
   * @return {*}  {IPSAppView}
   */
  getPSAppView(obj: IModel): Promise<IPSAppView>;
  getPSAppView(strPath: string): Promise<IPSAppView>;
  async getPSAppView(obj: IModel | string): Promise<IPSAppView> {
    if (isObject(obj)) {
      return this.getPSModel4(
        this.app,
        'app.view.IPSAppView',
        obj as IModel,
      ) as IPSAppView;
    }
    if (this.store.viewPath.size === 0) {
      this.store.fillViewPath(this.app);
    }
    const str = obj as string;
    return this.getPSModel('app.view.IPSAppView', str) as Promise<IPSAppView>;
  }

  /**
   * 获取应用实体
   *
   * @param {string} strPath
   * @return {*}  {Promise<IPSAppDataEntity>}
   */
  getPSAppDataEntity(obj: IModel): Promise<IPSAppDataEntity>;
  getPSAppDataEntity(strPath: string): Promise<IPSAppDataEntity>;
  async getPSAppDataEntity(obj: IModel | string): Promise<IPSAppDataEntity> {
    if (isObject(obj)) {
      return this.getPSModel4(
        this.app,
        'app.dataentity.IPSAppDataEntity',
        obj as IModel,
      ) as IPSAppDataEntity;
    }
    const str = obj as string;
    if (this.store.entityPath.size === 0) {
      this.store.fillEntityPath(this.app);
    }
    return this.getPSModel(
      'app.dataentity.IPSAppDataEntity',
      str,
    ) as Promise<IPSAppDataEntity>;
  }

  /**
   * 获取代码表
   *
   * @author chitanda
   * @date 2021-04-12 11:04:37
   * @param {string} strPath
   * @return {*}  {IPSModelObject}
   */
  getPSAppCodeList(strPath: string): IPSModelObject {
    if (this.store.codeListPath.size === 0) {
      this.store.fillCodeListPath(this.app);
    }
    let obj = this.store.codeListPath.get(strPath);
    // 当未实例化时，实例化对象并缓存
    if (obj && typeof obj.instanceof !== 'function') {
      const t = this.createPSModelObject(
        null,
        'app.codelist.IPSAppCodeList',
        obj,
      );
      t.init(
        this.getPSModelService('app.codelist.IPSAppCodeList', t),
        null,
        null,
        obj,
      );
      this.store.codeListPath.set(strPath, t);
      obj = t;
    }
    return obj as IPSModelObject;
  }

  /**
   * 获取应用功能
   *
   * @author chitanda
   * @date 2021-04-12 10:04:41
   * @param {string} tag
   * @return {*}  {IPSModelObject}
   */
  getPSAppFunc(tag: string): IPSModelObject {
    if (this.store.appFuncs.size === 0) {
      this.store.fillAppFuncs(this.app);
    }
    let obj = this.store.appFuncs.get(tag);
    // 当未实例化时，实例化对象并缓存
    if (obj && typeof obj.instanceof !== 'function') {
      const t = this.createPSModelObject(null, 'app.func.IPSAppFunc', obj);
      t.init(this.getPSModelService('app.func.IPSAppFunc', t), null, null, obj);
      this.store.appFuncs.set(obj.codeName, t);
      obj = t;
    }
    return obj as IPSModelObject;
  }

  /**
   * 获取界面行为
   *
   * @author chitanda
   * @date 2021-04-12 10:04:47
   * @param {string} tag
   * @return {*}  {IPSModelObject}
   */
  getPSUIAction(tag: string): IPSModelObject {
    if (this.store.appDEUIAction.size === 0) {
      this.store.fillAppDEUIActions(this.app);
    }
    let obj = this.store.appDEUIAction.get(tag);
    // 当未实例化时，实例化对象并缓存
    if (obj && typeof obj.instanceof !== 'function') {
      const t = this.createPSModelObject(null, 'view.IPSUIAction', obj);
      t.init(this.getPSModelService('view.IPSUIAction', t), null, null, obj);
      this.store.appDEUIAction.set(obj.codeName, t);
      obj = t;
    }
    return obj as IPSModelObject;
  }

  /**
   * 根据视图标识获取视图模型路径
   *
   * @param {string} tag 实体 + 视图 全小写
   * @return {*}  {string}
   */
  getPSAppViewPath(tag: string): string {
    this.store.fillViewTagPath(this.app);
    return this.store.viewTagPath.get(tag);
  }

  /**
   * 获取多语言值
   *
   * @author chitanda
   * @date 2021-05-27 16:05:48
   * @param {string} key
   * @return {*}  {string}
   */
  getPSLang(key: string): string {
    let val = '';
    if (isNilOrEmpty(val) && this.store.languageCache.has(key)) {
      val = this.store.languageCache.get(key);
    }
    return val;
  }
}
